package com.kakarote.hrm.controller;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.kakarote.common.log.annotation.OperateLog;
import com.kakarote.common.log.entity.OperationLog;
import com.kakarote.common.log.entity.OperationResult;
import com.kakarote.common.log.enums.ApplyEnum;
import com.kakarote.common.log.enums.BehaviorEnum;
import com.kakarote.common.log.enums.OperateObjectEnum;
import com.kakarote.common.log.enums.OperateTypeEnum;
import com.kakarote.core.common.Result;
import com.kakarote.core.common.enums.SystemCodeEnum;
import com.kakarote.core.entity.BasePage;
import com.kakarote.core.feign.admin.entity.AdminRole;
import com.kakarote.core.feign.admin.service.AdminService;
import com.kakarote.core.utils.UserUtil;
import com.kakarote.hrm.common.EmployeeHolder;
import com.kakarote.hrm.constant.EmployeeLableGroup;
import com.kakarote.hrm.constant.FieldTypeEnum;
import com.kakarote.hrm.constant.IsEnum;
import com.kakarote.hrm.entity.BO.*;
import com.kakarote.hrm.entity.PO.*;
import com.kakarote.hrm.entity.VO.*;
import com.kakarote.hrm.service.HrmUploadExcelService;
import com.kakarote.hrm.service.IHrmDataPushLogService;
import com.kakarote.hrm.service.IHrmEmployeeEncryptFieldService;
import com.kakarote.hrm.service.IHrmEmployeeService;
import com.kakarote.hrm.task.GzwEmployeeTask;
import com.kakarote.hrm.task.PushDataTask;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 员工表 前端控制器
 * </p>
 *
 * @author huangmingbo
 * @since 2020-05-12
 */
@RestController
@RequestMapping("/hrmEmployee")
@Api(tags = "员工管理")
@Slf4j
public class HrmEmployeeController {

    @Autowired
    private IHrmEmployeeService employeeService;

    @Autowired
    private HrmUploadExcelService excelService;
    @Autowired
    private PushDataTask pushDataTask;
    @Autowired
    private IHrmEmployeeEncryptFieldService employeeEncryptFieldService;
    @Autowired
    private AdminService adminService;
    @Autowired
    private GzwEmployeeTask gzwEmployeeTask;

    @PostMapping("/queryLoginEmployee")
    @ApiOperation("查询登录员工")
    public Result<EmployeeInfo> queryLoginEmployee() {
        EmployeeInfo employeeInfo = Optional.ofNullable(EmployeeHolder.getEmployeeInfo()).orElse(new EmployeeInfo());
        employeeInfo.setIsAdmin(EmployeeHolder.isHrmAdmin());
        if (!EmployeeHolder.isHrmAdmin()){
            List<AdminRole> roles = adminService.queryRoleByRoleTypeAndUserId(9).getData();
            if (roles != null && !roles.isEmpty()){
                for (AdminRole role : roles) {
                    if ("人力资源管理员".equals(role.getRoleName()) || "上级角色".equals(role.getRoleName())){
                        employeeInfo.setIsAdmin(true);
                        break;
                    }
                }
            }
        }
        employeeInfo.setIsSuperAdmin(UserUtil.isAdmin());
        return Result.ok(employeeInfo);
    }

    @PostMapping("/addEmployee")
    @ApiOperation("新建员工")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.SAVE)
    public Result addEmployee(@Valid @RequestBody AddEmployeeBO employeeVO) {
        List<OperationLog> operationLogList = employeeService.add(employeeVO);
        return OperationResult.ok(operationLogList);
    }

    @PostMapping("/confirmEntry")
    @ApiOperation("确认入职")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.DETERMINE_ENTRY)
    public Result confirmEntry(@RequestBody AddEmployeeFieldManageBO employeeBO) {
        OperationLog operationLog = employeeService.confirmEntry(employeeBO);
        return OperationResult.ok(operationLog);
    }


    @PostMapping("/queryEmployeeStatusNum")
    @ApiOperation("查询每个员工状态的数量")
    public Result<Map<Integer, Long>> queryEmployeeStatusNum(@RequestBody QueryEmployeePageListBO employeePageListBO) {
        Map<Integer, Long> statusMap = employeeService.queryEmployeeStatusNum(employeePageListBO);
        return Result.ok(statusMap);
    }

    @PostMapping("/queryPageList")
    @ApiOperation("分页查询员工列表")
    public Result<BasePage<Map<String, Object>>> queryPageList(@RequestBody QueryEmployeePageListBO employeePageListBO) {
        BasePage<Map<String, Object>> map = employeeService.queryPageList(employeePageListBO);
        return Result.ok(map);
    }


    @GetMapping("/queryEmployeeDetailById/{empId}")
    @ApiOperation("查询员工详情")
    public Result<Map<String, Object>> queryEmployeeDetailById(@PathVariable("empId") Long empId) {
        Map<String, Object> map = employeeService.queryEmployeeDetailById(empId);
        return Result.ok(map);
    }

    @PostMapping("/queryAllEmployeeList")
    @ApiOperation("查询所用员工(表单选择使用)")
    public Result<List<SimpleHrmEmployeeVO>> queryAllEmployeeList(@RequestParam(name = "employeeName", required = false) String employeeName) {
        List<SimpleHrmEmployeeVO> list = employeeService.queryAllEmployeeList(employeeName);
        return Result.ok(list);
    }


    @PostMapping("/queryInspectionAllEmployeeList")
    @ApiOperation("查询考核范围可查询的所有员工(表单选择使用)")
    public Result<List<SimpleHrmEmployeeVO>> queryInspectionAllEmployeeList(@RequestParam(name = "employeeName", required = false) String employeeName) {
        List<SimpleHrmEmployeeVO> list = employeeService.queryInspectionAllEmployeeList(employeeName);
        return Result.ok(list);
    }

    @PostMapping("/queryAttendanceAllEmployeeList")
    @ApiOperation("查询考勤范围可查询的所有员工(表单选择使用)")
    public Result<List<SimpleHrmEmployeeVO>> queryAttendanceAllEmployeeList(@RequestParam(name = "employeeName", required = false) String employeeName) {
        List<SimpleHrmEmployeeVO> list = employeeService.queryAttendanceAllEmployeeList(employeeName);
        return Result.ok(list);
    }

    @PostMapping("/queryDeptEmployeeList/{deptId}")
    @ApiOperation("查询部门员工列表")
    public Result<DeptEmployeeListVO> queryDeptEmployeeList(@PathVariable("deptId") Long deptId) {
        DeptEmployeeListVO deptEmployeeListVO = employeeService.queryDeptEmployeeList(deptId);
        return Result.ok(deptEmployeeListVO);
    }

    @PostMapping("/queryInspectionDeptEmployeeList/{deptId}")
    @ApiOperation("查询部门员工列表")
    public Result<DeptEmployeeListVO> queryInspectionDeptEmployeeList(@PathVariable("deptId") Long deptId) {
        DeptEmployeeListVO deptEmployeeListVO = employeeService.queryInspectionDeptEmployeeList(deptId);
        return Result.ok(deptEmployeeListVO);
    }

    @PostMapping("/queryAttendDeptEmployeeList/{deptId}")
    @ApiOperation("查询部门员工列表(考勤打卡调用)")
    public Result<DeptEmployeeListVO> queryAttendDeptEmployeeList(@PathVariable("deptId") Long deptId) {
        DeptEmployeeListVO deptEmployeeListVO = employeeService.queryAttendDeptEmployeeList(deptId);
        return Result.ok(deptEmployeeListVO);
    }

    @PostMapping("/queryDeptEmpListByUser")
    @ApiOperation("查询部门用户列表(hrm添加员工使用)")
    public Result<Set<SimpleHrmEmployeeVO>> queryDeptEmpListByUser(@RequestBody DeptUserListByUserBO deptUserListByUserBO) {
        Set<SimpleHrmEmployeeVO> userList = employeeService.queryDeptUserListByUser(deptUserListByUserBO);
        return Result.ok(userList);
    }

    @PostMapping("/queryInEmployeeList")
    @ApiOperation("查询在职员工(表单选择使用)")
    public Result<List<SimpleHrmEmployeeVO>> queryInEmployeeList() {
        List<SimpleHrmEmployeeVO> list = employeeService.queryInEmployeeList();
        return Result.ok(list);
    }


    @PostMapping("/personalInformation/{employeeId}")
    @ApiOperation("个人基本信息")
    public Result<PersonalInformationVO> personalInformation(@PathVariable("employeeId") Long employeeId) {
        PersonalInformationVO personalInformationVO = employeeService.personalInformation(employeeId);
        return Result.ok(personalInformationVO);
    }

    @PostMapping("/personalInformationHighlight")
    @ApiOperation("高亮显示个人基本信息")
    public Result<Object> personalInformationHighlight(@RequestBody QueryEmployeePostInformation employeePostInformation) {
        if (StrUtil.isNotEmpty(employeePostInformation.getQueryContent()) && StrUtil.isNotEmpty(employeePostInformation.getQueryContent().trim())){
            return Result.ok(employeeService.personalInformationHighlight(employeePostInformation));
        }else {
            return Result.ok(employeeService.personalInformation(employeePostInformation.getEmployeeId()));
        }
    }

    @PostMapping("/rewardsPunishments/{employeeId}")
    @ApiOperation("员工奖惩信息")
    public Result<List<HrmEmployeeRewardsPunishmentsVO>> queryRewardsPunishmentsList(@PathVariable("employeeId") Long employeeId) {
        List<HrmEmployeeRewardsPunishmentsVO> list = employeeService.queryRewardsPunishmentsList(employeeId);
        return Result.ok(list);
    }

    @PostMapping("/addRewardsPunishments")
    @ApiOperation("添加员工奖惩信息")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.SAVE)
    public Result addRewardsPunishments(@Validated @RequestBody HrmEmployeeRewardsPunishments punishments) {
        OperationLog operationLog = employeeService.saveOrUpdateRewardsPunishments(punishments);
        return OperationResult.ok(operationLog);
    }

    @PostMapping("/setRewardsPunishments")
    @ApiOperation("修改员工奖惩信息")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.UPDATE)
    public Result setRewardsPunishments(@Validated @RequestBody HrmEmployeeRewardsPunishments punishments) {
        OperationLog operationLog = employeeService.saveOrUpdateRewardsPunishments(punishments);
        return OperationResult.ok(operationLog);
    }

    @PostMapping("/deleteRewardsPunishments/{id}")
    @ApiOperation("删除员工奖惩信息")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.DELETE)
    public Result deleteRewardsPunishments(@PathVariable("id") Long id) {
        OperationLog operationLog = employeeService.deleteRewardsPunishments(id);
        return OperationResult.ok(operationLog);
    }

    @PostMapping("/queryById/{employeeId}")
    @ApiOperation("查询员工详情")
    public Result<HrmEmployee> queryById(@PathVariable("employeeId") Long employeeId) {
        HrmEmployee hrmEmployee = employeeService.queryById(employeeId);
        return Result.ok(hrmEmployee);
    }

    @PostMapping("/updateInformation")
    @ApiOperation("修改员工基本信息")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.UPDATE)
    public Result updateInformation(@RequestBody UpdateInformationBO updateInformationBO) {
        OperationLog operationLog = employeeService.updateInformation(updateInformationBO);
        return OperationResult.ok(operationLog);
    }

    @PostMapping("/updateKeyFieldAudit")
    @ApiOperation("员工关键字段修改审核")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.UPDATE)
    public Result updateKeyFieldAudit(@RequestBody Map<String,UpdateInformationBO> informationBOMap) {
        OperationLog operationLog = employeeService.updateKeyFieldAudit(informationBOMap);
        return OperationResult.ok(operationLog);
    }

    @PostMapping("/updatePostLevelAudit")
    @ApiOperation("职务层级调整提交审核")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.UPDATE)
    public Result updatePostLevelAudit(@RequestBody EmployeePostLevelVo employeePostLevelVo) {
        OperationLog operationLog = employeeService.updatePostLevelAudit(employeePostLevelVo);
        return OperationResult.ok(operationLog);
    }


    @PostMapping("/updateCommunication")
    @ApiOperation("修改通讯信息")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.UPDATE)
    public Result updateCommunication(@RequestBody UpdateInformationBO updateInformationBO) {
        OperationLog operationLog = employeeService.updateCommunication(updateInformationBO);
        return OperationResult.ok(operationLog);
    }


    @PostMapping("/addExperience")
    @ApiOperation("添加教育经历")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.UPDATE)
    public Result addOrUpdateEduExperience(@Validated @RequestBody HrmEmployeeEducationExperience educationExperience) {
        OperationLog operationLog = employeeService.addOrUpdateEduExperience(educationExperience);
        return OperationResult.ok(operationLog);
    }

    @PostMapping("/setEduExperience")
    @ApiOperation("修改教育经历")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.UPDATE)
    public Result setEduExperience(@Validated @RequestBody HrmEmployeeEducationExperience educationExperience) {
        OperationLog operationLog = employeeService.addOrUpdateEduExperience(educationExperience);
        return OperationResult.ok(operationLog);
    }


    @PostMapping("/deleteEduExperience/{educationId}")
    @ApiOperation("删除教育经历")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.UPDATE)
    public Result deleteEduExperience(@PathVariable("educationId") Long educationId) {
        OperationLog operationLog = employeeService.deleteEduExperience(educationId);
        return OperationResult.ok(operationLog);
    }

    @PostMapping("/addWorkExperience")
    @ApiOperation("添加工作经历")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.UPDATE)
    public Result addWorkExperience(@Validated @RequestBody HrmEmployeeWorkExperience workExperience) {
        OperationLog operationLog = employeeService.addOrUpdateWorkExperience(workExperience);
        return OperationResult.ok(operationLog);
    }

    @PostMapping("/setWorkExperience")
    @ApiOperation("修改工作经历")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.UPDATE)
    public Result setWorkExperience(@Validated @RequestBody HrmEmployeeWorkExperience workExperience) {
        OperationLog operationLog = employeeService.addOrUpdateWorkExperience(workExperience);
        return OperationResult.ok(operationLog);
    }


    @PostMapping("/deleteWorkExperience/{workExpId}")
    @ApiOperation("删除工作经历")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.UPDATE)
    public Result deleteWorkExperience(@PathVariable("workExpId") Long workExpId) {
        OperationLog operationLog = employeeService.deleteWorkExperience(workExpId);
        return OperationResult.ok(operationLog);
    }


    @PostMapping("/addCertificate")
    @ApiOperation("添加证书")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.UPDATE)
    public Result addCertificate(@Validated @RequestBody HrmEmployeeCertificate certificate) {
        employeeService.addOrUpdateCertificate(certificate);
        return Result.ok();
    }

    @PostMapping("/setCertificate")
    @ApiOperation("修改证书")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.UPDATE)
    public Result setCertificate(@Validated @RequestBody HrmEmployeeCertificate certificate) {
        employeeService.addOrUpdateCertificate(certificate);
        return Result.ok();
    }

    @PostMapping("/deleteCertificate/{certificateId}")
    @ApiOperation("删除证书")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.UPDATE)
    public Result deleteCertificate(@PathVariable("certificateId") Long certificateId) {
        employeeService.deleteCertificate(certificateId);
        return Result.ok();
    }


    @PostMapping("/addTechnical")
    @ApiOperation("添加职业技术职务")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.UPDATE)
    public Result addTechnical(@Validated @RequestBody HrmEmployeeTechnical technical) {
        employeeService.addOrUpdateTechnical(technical);
        return Result.ok();
    }

    @PostMapping("/setTechnical")
    @ApiOperation("修改职业技术职务")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.UPDATE)
    public Result setTechnical(@Validated @RequestBody HrmEmployeeTechnical technical) {
        employeeService.addOrUpdateTechnical(technical);
        return Result.ok();
    }

    @PostMapping("/deleteTechnical/{technicalId}")
    @ApiOperation("删除职业技术职务")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.UPDATE)
    public Result deleteTechnical(@PathVariable("technicalId") Long technicalId) {
        employeeService.deleteTechnical(technicalId);
        return Result.ok();
    }

    @PostMapping("/addSpecialWorker")
    @ApiOperation("添加专技工人证书")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.UPDATE)
    public Result addSpecialWorker(@Validated @RequestBody HrmEmployeeSpecialWorker specialWorker) {
        employeeService.addOrUpdateSpecialWorker(specialWorker);
        return Result.ok();
    }

    @PostMapping("/setSpecialWorker")
    @ApiOperation("修改专技工人证书")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.UPDATE)
    public Result setSpecialWorker(@Validated @RequestBody HrmEmployeeSpecialWorker specialWorker) {
        employeeService.addOrUpdateSpecialWorker(specialWorker);
        return Result.ok();
    }

    @PostMapping("/deleteSpecialWorker/{specialWorkerId}")
    @ApiOperation("删除专技工人证书")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.UPDATE)
    public Result deleteSpecialWorker(@PathVariable("specialWorkerId") Long specialWorkerId) {
        employeeService.deleteSpecialWorker(specialWorkerId);
        return Result.ok();
    }


    @PostMapping("/addTrainingExperience")
    @ApiOperation("添加培训经历")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.UPDATE)
    public Result addTrainingExperience(@Validated @RequestBody HrmEmployeeTrainingExperience trainingExperience) {
        OperationLog operationLog = employeeService.addOrUpdateTrainingExperience(trainingExperience);
        return OperationResult.ok(operationLog);
    }

    @PostMapping("/setTrainingExperience")
    @ApiOperation("修改培训经历")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.UPDATE)

    public Result setTrainingExperience(@Validated @RequestBody HrmEmployeeTrainingExperience trainingExperience) {
        OperationLog operationLog = employeeService.addOrUpdateTrainingExperience(trainingExperience);
        return OperationResult.ok(operationLog);
    }

    @PostMapping("/deleteTrainingExperience/{trainingId}")
    @ApiOperation("删除培训经历")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.UPDATE)

    public Result deleteTrainingExperience(@PathVariable("trainingId") Long trainingId) {
        OperationLog operationLog = employeeService.deleteTrainingExperience(trainingId);
        return OperationResult.ok(operationLog);
    }

    @PostMapping("/queryContactsAddField")
    @ApiOperation("查询联系人添加字段")
    public Result<List<HrmEmployeeField>> queryContactsAddField() {
        List<HrmEmployeeField> hrmEmployeeFieldList = employeeService.queryContactsAddField();
        return Result.ok(hrmEmployeeFieldList);
    }


    @PostMapping("/addContacts")
    @ApiOperation("添加联系人")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.UPDATE)
    public Result addContacts(@RequestBody UpdateInformationBO updateInformationBO) {
        OperationLog operationLog = employeeService.addOrUpdateContacts(updateInformationBO);
        return OperationResult.ok(operationLog);
    }

    @PostMapping("/setContacts")
    @ApiOperation("修改联系人")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.UPDATE)
    public Result setContacts(@RequestBody UpdateInformationBO updateInformationBO) {
        OperationLog operationLog = employeeService.addOrUpdateContacts(updateInformationBO);
        return OperationResult.ok(operationLog);
    }


    @PostMapping("/deleteContacts/{contractsId}")
    @ApiOperation("删除联系人")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.UPDATE)

    public Result deleteContacts(@PathVariable("contractsId") Long contractsId) {
        OperationLog operationLog = employeeService.deleteContacts(contractsId);
        return OperationResult.ok(operationLog);
    }

    @PostMapping("/deleteByIds")
    @ApiOperation("删除员工")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.DELETE)
    public Result deleteByIds(@RequestBody List<Long> employeeIds) {
        List<OperationLog> operationLogList = employeeService.deleteByIds(employeeIds);
        return OperationResult.ok(operationLogList);
    }


    @PostMapping("/become")
    @ApiOperation("转正")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.BECOME)
    public Result become(@RequestBody HrmEmployeeChangeRecord hrmEmployeeChangeRecord) {
        OperationLog operationLog = employeeService.change(hrmEmployeeChangeRecord);
        return OperationResult.ok(operationLog);
    }

    @PostMapping("/changePost")
    @ApiOperation("调整部门/岗位")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.CHANGE_POST)
    public Result changePost(@RequestBody HrmEmployeeChangeRecord hrmEmployeeChangeRecord) {
        OperationLog operationLog = employeeService.change(hrmEmployeeChangeRecord);
        return OperationResult.ok(operationLog);
    }

    @PostMapping("/promotion")
    @ApiOperation("晋升/降级")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.PROMOTION)
    public Result promotion(@RequestBody HrmEmployeeChangeRecord hrmEmployeeChangeRecord) {
        OperationLog operationLog = employeeService.change(hrmEmployeeChangeRecord);
        return OperationResult.ok(operationLog);
    }

    @PostMapping("/updateInsuranceScheme")
    @ApiOperation("修改社保方案")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.INSURANCE_SCHEME)
    public Result updateInsuranceScheme(@RequestBody UpdateInsuranceSchemeBO updateInsuranceSchemeBO) {
        List<OperationLog> operationLogs = employeeService.updateInsuranceScheme(updateInsuranceSchemeBO);
        return OperationResult.ok(operationLogs);
    }


    @PostMapping("/againOnboarding")
    @ApiOperation("再入职")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.REINSTATEMENT)
    public Result againOnboarding(@RequestBody AddEmployeeFieldManageBO employeeBO) {
        OperationLog operationLog = employeeService.againOnboarding(employeeBO);
        return OperationResult.ok(operationLog);
    }

    /**
     * @author wyq
     * 获取导入模板
     */
    @PostMapping("/downloadExcel")
    @ApiOperation("获取导入模板")
    public void downloadExcel(HttpServletResponse response) {
        List<HrmEmployeeField> hrmEmployeeFields = employeeService.downloadExcelFiled();
        HSSFWorkbook wb = new HSSFWorkbook();
        try{
            // 获取枚举值
            EmployeeLableGroup[] values = EmployeeLableGroup.values();
            for (int i = 0; i < values.length; i++) {
                downloadExcelForSheet(hrmEmployeeFields, wb, values[i].getValue(), values[i].getName());
            }
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setCharacterEncoding("UTF-8");
            //test.xls是弹出下载对话框的文件名，不能为中文，中文请自行编码
            response.setHeader("Content-Disposition", "attachment;filename=employee_import.xls");
            wb.write(response.getOutputStream());
        } catch (Exception e) {
            log.error("error",e);
        } finally {
            try {
                wb.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

    }

    /**
     * 导出对应sheet
     * @param hrmEmployeeFieldsList
     * @param wb
     * @param sheetGroup
     * @param sheetName
     */
    public void downloadExcelForSheet(List<HrmEmployeeField> hrmEmployeeFieldsList,
                                      HSSFWorkbook wb, int sheetGroup, String sheetName){

        //判断是否允许导出模版
        if(IsEnum.YES.getValue() != EmployeeLableGroup.valueOfStatus(sheetGroup)){
            return ;
        }

        List<HrmEmployeeField> hrmEmployeeFields;
        if(EmployeeLableGroup.LABLE_GROUP_1.getValue() == sheetGroup){
            hrmEmployeeFields = hrmEmployeeFieldsList.stream()
                    .filter(t -> t.getLabelGroup() == sheetGroup || t.getLabelGroup() == EmployeeLableGroup.LABLE_GROUP_2.getValue())
                    .sorted(Comparator.comparing(HrmEmployeeField::getLabelGroup).thenComparing(HrmEmployeeField::getSorting))
                    .collect(Collectors.toList());
        }else{
            hrmEmployeeFields = hrmEmployeeFieldsList.stream()
                    .filter(t -> t.getLabelGroup() == sheetGroup || t.getLabelGroup() == EmployeeLableGroup.LABLE_GROUP_99.getValue())
                    .sorted(Comparator.comparing(HrmEmployeeField::getSorting))
                    .collect(Collectors.toList());
        }
        if(hrmEmployeeFields.size() <= 0){
            //判断如果对应字段不存在则默认不导入到模版中
            return;
        }

        HSSFSheet sheet = wb.createSheet(sheetName);
        sheet.setDefaultRowHeight((short) 400);
        CellStyle textStyle = wb.createCellStyle();
        DataFormat format = wb.createDataFormat();
        textStyle.setDataFormat(format.getFormat("@"));
        for (int i = 0; i < hrmEmployeeFields.size(); i++) {
            HrmEmployeeField hrmEmployeeField = hrmEmployeeFields.get(i);
            if (Objects.equals(hrmEmployeeField.getType(), FieldTypeEnum.DATE.getValue())) {
                CellStyle dateStyle = wb.createCellStyle();
                DataFormat dateFormat = wb.createDataFormat();
                dateStyle.setDataFormat(dateFormat.getFormat("yyyy\"-\"m\"-\"d"));
                sheet.setDefaultColumnStyle(i, dateStyle);
            } else if (Objects.equals(hrmEmployeeField.getType(), FieldTypeEnum.DATETIME.getValue())) {
                CellStyle dateStyle = wb.createCellStyle();
                DataFormat dateFormat = wb.createDataFormat();
                dateStyle.setDataFormat(dateFormat.getFormat(DatePattern.NORM_DATETIME_PATTERN));
                sheet.setDefaultColumnStyle(i, dateStyle);
            } else {
                sheet.setDefaultColumnStyle(i, textStyle);
            }
            sheet.setColumnWidth(i, 20 * 256);
        }
        CellStyle cellStyle = wb.createCellStyle();
        HSSFRow titleRow = sheet.createRow(0);
        cellStyle.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex());
        cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        Font font = wb.createFont();
        font.setBold(true);
        font.setFontHeightInPoints((short) 16);
        cellStyle.setFont(font);
        titleRow.createCell(0).setCellValue(sheetName + "导入模板(*)为必填项");
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        titleRow.getCell(0).setCellStyle(cellStyle);
        CellRangeAddress region = new CellRangeAddress(0, 0, 0, hrmEmployeeFields.size() - 1);
        sheet.addMergedRegion(region);
        HSSFRow row = sheet.createRow(1);
        HSSFRow row2 = sheet.createRow(2);
        for (int i = 0; i < hrmEmployeeFields.size(); i++) {
            HrmEmployeeField hrmEmployeeField = hrmEmployeeFields.get(i);
            // 在第一行第一个单元格，插入选项
            HSSFCell cell = row.createCell(i);

            // 写一行示例数据
            HSSFCell cell2 = createDefaultCell(row2, i, hrmEmployeeField);
            // 普通写入操作
            String cellValue;
            if (hrmEmployeeField.getIsNull() == 1) {
                cellValue = hrmEmployeeField.getName() + "(*)";
            } else {
                cellValue = hrmEmployeeField.getName();
            }
            if (StrUtil.isNotEmpty(hrmEmployeeField.getRemark())) {
                cellValue += "(" + hrmEmployeeField.getRemark() + ")";
            }
            if (hrmEmployeeField.getType().equals(FieldTypeEnum.DATE.getValue())) {
                cellValue += "-例:[2020-10-01]";
            }
            cell.setCellValue(cellValue);
            String options = hrmEmployeeField.getOptions();
            if (StrUtil.isNotEmpty(options)) {
                List<String> setting = new ArrayList<>();
                JSONArray array = JSON.parseArray(options);
                for (int j = 0; j < array.size(); j++) {
                    if (j == 0) {
                        cell2.setCellValue(array.getJSONObject(j).getString("name"));
                    }
                    setting.add(array.getJSONObject(j).getString("name"));
                }
                String fieldName = hrmEmployeeField.getFieldName();
                HSSFSheet hidden = wb.createSheet(fieldName);
                HSSFCell sheetCell;
                for (int j = 0, length = setting.size(); j < length; j++) {
                    String name = setting.get(j);
                    HSSFRow sheetRow = hidden.createRow(j);
                    sheetCell = sheetRow.createCell(0);
                    sheetCell.setCellValue(name);
                }
                Name namedCell = wb.createName();
                namedCell.setNameName(fieldName);
                namedCell.setRefersToFormula(fieldName + "!$A$1:$A$" + setting.size());
                CellRangeAddressList regions = new CellRangeAddressList(2, Integer.MAX_VALUE, i, i);
                DVConstraint constraint = DVConstraint.createFormulaListConstraint(fieldName);
                HSSFDataValidation dataValidation = new HSSFDataValidation(regions, constraint);
                wb.setSheetHidden(wb.getSheetIndex(hidden), true);
                sheet.addValidationData(dataValidation);
            }
        }
    }

    private static HSSFCell createDefaultCell(HSSFRow row2, int i, HrmEmployeeField hrmEmployeeField) {
        HSSFCell cell2 = row2.createCell(i);
        if ("employee_name".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("张三");
        }
        if ("mobile".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("17707008888");
        }
        if ("home_place".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("江西省南昌市高新区");
        }
        if ("id_number".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("360121199006173110");
        }
        if ("native_place".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("江西南昌");
        }
        if ("birth_place".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("江西南昌");
        }
        if ("height".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("180");
        }
        if ("language_level_name".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("四级");
        }
        if ("home_phone".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("10086");
        }
        if ("interest_name".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("读书");
        }
        if ("zip_code".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("330000");
        }
        if ("speciality".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("无");
        }
        if ("emergencyContactPhone".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("无");
        }
        if ("current_residence".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("江西南昌");
        }

        if ("org".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("机构名称");
        }
        if ("dept".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("部门名称");
        }
        if ("job_title".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("员工");
        }

        if ("graduate_school".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("南昌大学");
        }
        if ("major".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("会计");
        }
        if ("witness".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("无");
        }

        if ("relation".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("父子");
        }
        if ("contacts_name".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("张一");
        }
        if ("contacts_work_unit".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("江西达途数字技术有限公司");
        }
        if ("contacts_post".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("员工");
        }
        if ("contacts_address".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("江西南昌");
        }
        if ("contacts_phone".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("18807004888");
        }
        if (hrmEmployeeField.getType().equals(FieldTypeEnum.DATE.getValue())) {
            cell2.setCellValue("2020-10-01");
        }

        if ("work_unit".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("江西达途数字技术有限公司");
        }
        if ("post".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("员工");
        }
        if ("witness".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("18807004888");
        }

        if ("technical_name".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("会计师");
        }
        if ("technical_level".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("一级");
        }

        if ("certificate_name".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("会计执照");
        }
        if ("certificate_level".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("一级");
        }

        if ("employee_id".equals(hrmEmployeeField.getFieldName())) {
            cell2.setCellValue("填员工基本信息表身份证号");
        }
        if (hrmEmployeeField.getType().equals(FieldTypeEnum.DATE.getValue())) {
            cell2.setCellValue("2020-10-01");
        }
        return cell2;
    }

    /**
     * @author wyq
     * 员工导入
     */
    @PostMapping("/uploadExcel")
    @ApiOperation("员工导入")
    public Result<Long> uploadExcel(@RequestParam("file") MultipartFile file, @RequestParam("repeatHandling") Integer repeatHandling) {
        UploadExcelBO uploadExcelBO = new UploadExcelBO();
        uploadExcelBO.setRepeatHandling(repeatHandling);
        Long messageId = excelService.uploadExcel(file, uploadExcelBO);
        return Result.ok(messageId);
    }

    @PostMapping("/export")
    @ApiOperation("导出员工")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.EXCEL_EXPORT, type = OperateTypeEnum.EXPORT)
    public void export(HttpServletResponse response,@RequestBody QueryEmployeePageListBO employeePageListBO) throws IOException {
        employeeService.exportExcel(response,employeePageListBO);
    }

    @PostMapping("/adminAddEmployee")
    @ApiOperation("从系统用户添加员工")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.SAVE)
    public Result adminAddEmployee(@RequestBody List<AddEmployeeBO> employeeList) {
        List<OperationLog> operationLogs = employeeService.adminAddEmployee(employeeList);
        return OperationResult.ok(operationLogs);
    }

    @PostMapping("/queryIsInHrm")
    @ApiOperation("查询登陆用户是否在人资员工中")
    public Result<Boolean> queryIsInHrm() {
        EmployeeInfo employeeInfo = employeeService.queryEmployeeInfoByMobile(UserUtil.getUser().getUsername());
        return Result.ok(Objects.nonNull(employeeInfo));
    }

    @PostMapping("/field")
    @ApiOperation("查询新增所需字段")
    public Result<List> queryEmployeeField(@ApiParam("入职状态 1 在职 2 待入职") @RequestParam(value = "entryStatus") Integer entryStatus) {
        return Result.ok(employeeService.queryEmployeeField(entryStatus));
    }

    @PostMapping("/addEmployeeField")
    @ApiOperation("新建自定义字段员工")
    @OperateLog(apply = ApplyEnum.HRM, object = OperateObjectEnum.HRM_EMPLOYEE, behavior = BehaviorEnum.SAVE)
    public Result addEmployee(@RequestBody AddEmployeeFieldManageBO addEmployeeFieldManageBO) {
        List<OperationLog> operationLogList = employeeService.addEmployeeField(addEmployeeFieldManageBO);
        return OperationResult.ok(operationLogList);
    }

    @PostMapping("/employeeMove")
    @ApiOperation("员工拖拽")
    public Result employeeMove(@Valid @RequestBody EmployeeMoveBO employeeMoveBO) {
        employeeService.employeeMove(employeeMoveBO);
        return Result.ok();
    }

    @GetMapping("/dataSync")
    @ApiOperation("数据同步")
    public Result employeeDataSync() {
        pushDataTask.pushEmployee("手动同步员工数据");
        return Result.ok();
    }

    @PostMapping("/exportEmployeeUser")
    @ApiOperation("导出员工用户数据")
    public void exportEmployeeUser(HttpServletResponse response) throws IOException{
        employeeService.exportEmployeeUser(response);
    }

    @GetMapping("/queerManageEmployeeIdList/{deptId}")
    @ApiOperation("查询领导班子的员工编号")
    public Result<Map<String ,Object>> queerManageEmployeeIdList(@PathVariable("deptId") Long deptId){
        Map<String, Object> map = new HashMap<>();
        List<String> manageList = employeeService.queerManageEmployeeIdList(deptId);
        map.put("manageList", manageList);
        map.put("fieldGroup", employeeEncryptFieldService.fieldListGroupByType());
        return Result.ok(map);
    }

    @PostMapping("/pushData")
    @ApiOperation("员工数据同步")
    public Result pushEmployeeData(@RequestBody List<Long> employeeIds) {
        if (employeeIds.isEmpty()){
            return Result.error(SystemCodeEnum.SYSTEM_ERROR,"请选择员工");
        }
        int i = employeeService.pushEmployeeData(employeeIds);
        if (i > 0) {
            return Result.ok();
        } else {
            return Result.error(SystemCodeEnum.SYSTEM_ERROR,"数据同步失败");
        }
    }

    @PostMapping("/gzwEmployeeSync")
    @ApiOperation("国资委员工基本信息同步")
    public Result gzwEmployeeSync() {
        try {
            boolean b = gzwEmployeeTask.syncEmployeeInformation();
            if (!b) {
                return Result.error(SystemCodeEnum.SYSTEM_ERROR, "国资委同步失败");
            }
            return Result.ok();
        } catch (Exception e) {
            log.error("国资委同步失败", e);
            return Result.error(SystemCodeEnum.SYSTEM_ERROR, "国资委员工基本信息同步失败");
        }
    }

    @PostMapping("/gzwPostSync")
    @ApiOperation("国资委员工岗位信息同步")
    public Result gzwPostSync() {
        try {
            boolean b = gzwEmployeeTask.syncPostInformation();
            if (!b) {
                return Result.error(SystemCodeEnum.SYSTEM_ERROR, "国资委同步失败");
            }
            return Result.ok();
        } catch (Exception e) {
            log.error("国资委同步失败", e);
            return Result.error(SystemCodeEnum.SYSTEM_ERROR, "国资委员工岗位信息同步失败");
        }
    }

    @PostMapping("/gzwEducationSync")
    @ApiOperation("国资委员工学历信息同步")
    public Result gzwEducationSync() {
        try {
            boolean b = gzwEmployeeTask.syncEducationExperience();
            if (!b) {
                return Result.error(SystemCodeEnum.SYSTEM_ERROR, "国资委员工学历信息同步失败");
            }
            return Result.ok();
        } catch (Exception e) {
            log.error("国资委同步失败", e);
            return Result.error(SystemCodeEnum.SYSTEM_ERROR, "国资委员工学历信息同步失败");
        }
    }


    @PostMapping("/gzwWorkSync")
    @ApiOperation("国资委员工工作信息同步")
    public Result gzwWorkSync() {
        try {
            boolean b = gzwEmployeeTask.syncWorkExperience();
            if (!b) {
                return Result.error(SystemCodeEnum.SYSTEM_ERROR, "国资委员工工作信息同步失败");
            }
            return Result.ok();
        } catch (Exception e) {
            log.error("国资委同步失败", e);
            return Result.error(SystemCodeEnum.SYSTEM_ERROR, "国资委员工工作信息同步失败");
        }
    }

    @PostMapping("/gzwDeptSync")
    @ApiOperation("国资委部门信息同步")
    public Result gzwDeptSync() {
        try {
            boolean b = gzwEmployeeTask.syncDeptInformation();
            if (!b) {
                return Result.error(SystemCodeEnum.SYSTEM_ERROR, "国资委部门信息同步失败");
            }
            return Result.ok();
        } catch (Exception e) {
            log.error("国资委同步失败", e);
            return Result.error(SystemCodeEnum.SYSTEM_ERROR, "国资委部门信息同步失败");
        }
    }
}

